<template>
  <el-dialog
    :title="showTitle"
    :visible.sync="dialogVisible"
    width="50%"
    :before-close="handleClose"
  >
    <el-form ref="form" :model="form" :rules="rules" label-width="120px">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="form.code"></el-input>
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select v-model="form.manager" placeholder="请选择部门负责人">
          <el-option
            v-for="item in userList"
            :key="item.id"
            :label="item.username"
            :value="item.username"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input type="textarea" v-model="form.introduce"></el-input>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button v-loading="loading" type="primary" @click="onConfirm"
        >确 定</el-button
      >
    </span>
  </el-dialog>
</template>

<script>
import {
  getDepartmentApi,
  addDepartmentApi,
  getDeptsById,
  editDeptsById
} from '@/api/department'
import { getUserSimple } from '@/api/user'
export default {
  props: {
    // 控制弹框显示与隐藏
    dialogVisible: {
      type: Boolean,
      default: false
    },
    // 获取当前选择点击的节点信息
    treeNode: {
      type: Object
    }
  },
  computed: {
    // 快捷取出当前节点的id
    nodeId() {
      return this.treeNode.id || ''
    },
    // 计算出是否是编辑状态
    isEdit() {
      // if (this.form.id) return true
      // return false
      return !!this.form.id
    },
    showTitle() {
      return this.isEdit ? '编辑部门' : '新增部门'
    }
  },
  data() {
    // 部门名称自定义校验
    const checkNameRepeat = async (rules, value, callback) => {
      // 定义一个变量假定部门名称不重复
      let repeatFlag = false
      // 请求接口获取所有的部门列表数据
      const { depts } = await getDepartmentApi()
      let children = []
      // 获取当前操作的节点的所有子部门，筛选出部门列表中的所有pid和当前节点id相同的数据
      if (this.isEdit) {
        // 编辑状态
        // 筛选出所有的兄弟节点，判断兄弟节点中name不能重复
        // 注意：把自己排除掉
        children = depts.filter(
          (item) => item.id !== this.nodeId && item.pid === this.treeNode.pid
        )
      } else {
        // 新增状态
        children = depts.filter((item) => item.pid === this.nodeId)
      }
      if (children && children.length > 0) {
        // 如果有子节点，判断一下子节点的name有没有和当前用户输入的value值相同的
        repeatFlag = children.some((item) => item.name === value)
      }
      repeatFlag ? callback(new Error('部门名称重复')) : callback()
    }
    // 部门编码自定义校验
    const checkCodeRepeat = async (rules, value, callback) => {
      // 定义一个变量假定部门名称不重复
      let repeatFlag = false
      // 请求接口获取所有的部门列表数据
      const { depts } = await getDepartmentApi()
      if (this.isEdit) {
        // 编辑状态下，对编码的判断要把自己排除掉
        repeatFlag = depts.some(
          (item) => item.id !== this.nodeId && item.code === value
        )
      } else {
        // 判断部门列表中只要有一个编码和用户输入的值相同就代表重复了
        repeatFlag = depts.some((item) => item.code === value)
      }
      repeatFlag ? callback(new Error('部门编码重复')) : callback()
    }
    return {
      // 表单数据绑定
      form: {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      },
      // 设置校验规则
      rules: {
        name: [
          { required: true, message: '请输入部门名称', trigger: 'blur' },
          {
            min: 1,
            max: 50,
            message: '长度在 1 到 50 个字符',
            trigger: 'blur'
          },
          { validator: checkNameRepeat, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '请输入部门名称', trigger: 'blur' },
          {
            min: 1,
            max: 50,
            message: '长度在 1 到 50 个字符',
            trigger: 'blur'
          },
          { validator: checkCodeRepeat, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '请选择部门负责人', trigger: 'change' }
        ],
        introduce: [
          { required: true, message: '请输入部门介绍', trigger: 'blur' },
          {
            min: 1,
            max: 300,
            message: '长度在 1 到 300 个字符',
            trigger: 'blur'
          }
        ]
      },
      userList: [], // 员工列表数据
      loading: false
    }
  },
  created() {
    // 获取用户列表，渲染select框中的负责人列表
    this.getUserList()
  },
  methods: {
    // 获取部门详情数据
    async getDepartmentInfo() {
      this.form = await getDeptsById(this.nodeId)
    },
    // 注意，弹框关闭之前监听的回调函数形参中有一个done参数
    // 只有执行了done()方法才能将弹框关掉
    handleClose(done) {
      // 关闭弹框之前清空表单
      this.form = {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      }
      // 注意：resetFields只能重置表单中使用的数据，
      // 表单中未使用的数据不能被重置
      this.$refs.form.resetFields()
      this.$emit('update:dialogVisible', false)
      // done()
    },
    // 确认按钮
    async onConfirm() {
      // 给确认按钮添加loading效果
      this.loading = true
      try {
        await this.$refs.form.validate()
        console.log('校验通过')
        if (this.isEdit) {
          await editDeptsById(this.nodeId, this.form)
        } else {
          // 校验通过，调用新增部门接口，并将当前节点的id传过去当做新增节点的pid
          await addDepartmentApi({ ...this.form, pid: this.nodeId })
        }
        this.$message.success('新增成功')
        // 关闭弹框
        this.handleClose()
        // 通知父组件，操作成功，刷新一下最新数据
        this.$emit('success')
      } catch (error) {}
      this.loading = false
    },
    // 获取员工简单列表
    async getUserList() {
      this.userList = await getUserSimple()
    }
  }
}
</script>

<style scoped>
.el-select {
  width: 500px;
}
.el-input {
  width: 500px;
}
.el-textarea {
  width: 500px;
}
</style>